package com.dries.netty.chat.netty;

import com.dries.netty.chat.processer.ChatProcesser;
import com.dries.netty.chat.session.ServerSession;
import com.dries.netty.chat.session.SessionMap;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;

import java.util.Map;

/**
 * @author Dries
 * @email 1451691457@qq.com
 */
public class TextWebSocketFrameHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {

        // 增加消息的引用计数（保留消息）,并将他写到 ChannelGroup 中所有已经连接的客户端
        ServerSession session = ServerSession.getSession(ctx);
        Map<String, String> result = ChatProcesser.getSingleInstance().onMessage(msg.text(), session);
        if (result != null && result.get("type") != null) {
            switch (result.get("type"))
            {
                case "msg":
                    SessionMap.getSingleInstance().sendToOthers(result, session);
                    break;
                case "init":
                    SessionMap.getSingleInstance().addSession(result, session);
                    break;
            }
        }
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {

        //是否握手成功，升级为 Websocket 协议
        if (evt == WebSocketServerProtocolHandler.ServerHandshakeStateEvent.HANDSHAKE_COMPLETE) {
            // 握手成功，移除 HttpRequestHandler，因此将不会接收到任何消息
            // 并把握手成功的 Channel 加入到 ChannelGroup 中
            ServerSession session = new ServerSession(ctx.channel());
            String echo = ChatProcesser.getSingleInstance().onOpen(session);
            SessionMap.getSingleInstance().sendMsg(ctx, echo);

        } else if (evt instanceof IdleStateEvent) {
            IdleStateEvent stateEvent = (IdleStateEvent) evt;
            if (stateEvent.state() == IdleState.READER_IDLE) {
                ServerSession session = ServerSession.getSession(ctx);
                SessionMap.getSingleInstance().remove(session);
                session.processError(null);
            }
        } else {
            super.userEventTriggered(ctx, evt);
        }

    }
}
